﻿using System;
using System.Collections.Generic;
using MongoDB;
using MongoDB.Driver;

namespace ToyChat.Server
{

    /// <summary>
    /// Used as a common interface to access the user / channel / whatever database
    /// </summary>
    public interface IDatabaseHandler
    {
        /// <summary>
        /// Attempts to find a user in the underlying database with the specified username
        /// </summary>
        /// <param name="username">The username of the user to find</param>
        /// <returns>A <see cref="UserInfo"/> object for the specified username</returns>
        IUserInfo FindUser(string username);

        /// <summary>
        /// Attempts to store the specified <see cref="UserInfo"/> in the underlying database
        /// </summary>
        /// <param name="info">The <see cref="UserInfo"/> to store</param>
        void StoreUser(IUserInfo info);

        /// <summary>
        /// Deletes the specified user from the underlying database
        /// </summary>
        /// <param name="info">The <see cref="UserInfo"/> to delete from the database</param>
        void DeleteUser(IUserInfo info);

        /// <summary>
        /// Hashes the specified password and returns the reult
        /// </summary>
        /// <param name="password">The password to get the hash for</param>
        /// <returns>The has for the specified password</returns>
        string GetPassHash(string password);

        /// <summary>
        /// Gets all channels currently available in the database
        /// </summary>
        /// <returns></returns>
        IEnumerable<Channel> GetChannels();

        /// <summary>
        /// Attempts to find a channel in the underlying database with the specified channel id
        /// </summary>
        /// <param name="channelID">The ID of the channel to find</param>
        /// <returns>A new <see cref="Channel"/> object created from the database, if it exists, otherwise null</returns>
        IChannel FindChannel(int channelID);

        /// <summary>
        /// Attempts to find a channel with the specified name in the database
        /// </summary>
        /// <param name="channelName">The name of the channel to find</param>
        /// <returns>The channel if it is found, otherwise null</returns>
        IChannel FindChannel(string channelName);

        /// <summary>
        /// Stores the specifiedchannel in the underlying database
        /// </summary>
        /// <param name="channel">The channel to store</param>
        void StoreChannel(IChannel channel);

        /// <summary>
        /// Deletes the specified channel from the underlying database
        /// </summary>
        /// <param name="channel">The channel to delete</param>
        void DeleteChannel(IChannel channel);

        /// <summary>
        /// Gets an <see cref="MongoCollection{T}"/> for the specified type
        /// </summary>
        /// <typeparam name="T">The Type to get the collection for</typeparam>
        /// <returns>An <see cref="MongoCollection{T}"/> for the specified type</returns>
        MongoCollection<T> GetCollection<T>() where T : class;
    }
}
